#include "cfiltermodel.h"
#include "isortable.h"

/**
 * CFilterModel类构造函数
 * 
 * 该构造函数初始化CFilterModel对象，继承自QSortFilterProxyModel。
 * 
 * @param parent 父对象的指针，默认为nullptr。
 */
CFilterModel::CFilterModel(QObject *parent):QSortFilterProxyModel(parent)
{
}

/**
 * 决定是否接受源模型的某一行。
 * 
 * @param source_row 源模型中的行号。
 * @param source_parent 源模型中的父索引。
 * @return 如果该行满足过滤条件，则返回true；否则返回false。
 */
bool CFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
    // 如果过滤内容为空，则接受所有行
    if (this->filterList().isEmpty())
           return true;

   auto index = sourceModel()->index(source_row, 0, source_parent);
   // 如果索引无效，则不接受该行
   if(!index.isValid())
        return false;
   
   // 检查当前索引是否匹配过滤条件
   if (matchesFilter(index) && !filterIsEmpty()){
       emit filterMatched(index);
       return true;
   }

   // 将搜索节点的子孙节点也显示
   // 检查父级祖先是否匹配过滤条件
   QModelIndex parent = source_parent;
   while (parent.isValid()) {
       if (matchesFilter(parent)){
           return true;
       }
       parent = parent.parent();
   }

   // 启用了setRecursiveFilteringEnabled，不需要递归检查了
    // 检查是否有匹配的后代（显示祖先节点）
//    if (hasMatchingDescendant(index))
//    {
//        return true;
//    }
    return false;
}

bool CFilterModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    return sourceModel()->setData(index,value,role);
}

/**
 * 应用新的过滤条件到模型。
 * 
 * 该函数用于更新模型的过滤字段和内容，然后触发过滤的重新计算。
 * 
 * @param newFilterField 过滤字段的名称，指定要应用过滤的属性或列。
 * @param newFilterContent 过滤内容，指定过滤条件的具体值或表达式。
 */
void CFilterModel::applyFilter(const QString &newFilterField, const QString &newFilterContent)
{
    clearFilterList();
    if(!newFilterContent.isEmpty())
        addFilter(QPair<QString,QString>(newFilterField,newFilterContent));
    invalidateFilter(); // 重新计算过滤，确保视图根据新的过滤条件更新
}

void CFilterModel::applyFilter(QList<QPair<QString, QString> > filterList)
{
    clearFilterList();
    setFilterList(filterList);
    invalidateFilter(); // 重新计算过滤，确保视图根据新的过滤条件更新
}

/**
 * 判断给定索引的数据是否匹配过滤条件。
 * 
 * @param index 需要判断的模型索引。
 * @return 如果匹配过滤条件返回true，否则返回false。
 */
/**
 * 检查给定的模型索引是否匹配已设置的过滤条件。
 * @param index 要检查的模型索引。
 * @return 如果模型索引匹配过滤条件，则返回true；否则返回false。
 */
bool CFilterModel::matchesFilter(const QModelIndex &index) const
{
    QVariant data = index.data(Qt::UserRole); // 从指定索引获取用户角色数据
    if (data.isValid()) // 检查数据是否有效
    {
        // 尝试将数据转换为QSharedPointer<IModel>类型
        auto filterData = qvariant_cast<QSharedPointer<IModel>>(data);
        if (filterData) // 检查转换是否成功
        {
            int bRet = true; // 默认认为匹配
            // 遍历所有过滤条件
            for(auto filterPair:m_filterList)
            {
                auto filterField = filterPair.first; // 过滤字段
                auto filterContent = filterPair.second; // 过滤内容
                // 获取字段值
                auto fieldValue = filterData->getFieldValueByFielddName(filterField);
                if (fieldValue.isValid()) // 检查字段值是否有效
                {
                    // 将字段值转换为字符串
                    auto fieldValueStr = filterData->variant2String(fieldValue);
                    // 检查字段值是否包含过滤内容
                    if(!fieldValueStr.contains(filterContent))
                    {
                        bRet = false; // 不包含则认为不匹配
                        break; // 直接退出循环
                    }
                }
            }
            return bRet; // 返回最终的匹配结果
        }
    }
    return false; // 数据无效或未找到匹配的过滤条件，返回false
}

/**
 * 判断给定索引是否有匹配的后代。
 * 
 * @param index 需要检查的模型索引。
 * @return 如果存在匹配的后代返回true，否则返回false。
 */
bool CFilterModel::hasMatchingDescendant(const QModelIndex &index) const
{
    if (!index.isValid())
        return false;

    int rowCount = sourceModel()->rowCount(index);
    for (int row = 0; row < rowCount; ++row)
    {
        QModelIndex childIndex = sourceModel()->index(row, 0, index);
        // 如果当前子索引或其后代匹配过滤条件，则存在匹配的后代
        if (matchesFilter(childIndex) || hasMatchingDescendant(childIndex))
            return true;
    }
    return false;
}

void CFilterModel::addFilter(QPair<QString, QString> filter)
{
    m_filterList.append(filter);
}

bool CFilterModel::filterIsEmpty() const
{
    bool ret = true;
    for(auto filterPair:m_filterList)
    {
        if(!filterPair.second.isEmpty())
        {
            ret = false;
            break;
        }
    }
    return ret;
}

/**
 * 比较两个模型索引项的数据是否满足小于关系。
 * 
 * @param source_left 第一个模型索引项，来源于模型的源数据。
 * @param source_right 第二个模型索引项，同样来源于模型的源数据。
 * @return 如果第一个模型索引项的数据小于第二个模型索引项的数据，则返回true；否则返回false。
 */
bool CFilterModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
    QVariant leftData = source_left.data(Qt::UserRole); // 从source_left获取用户定义的角色数据
    QSharedPointer<IModel> leftFilterData = nullptr;
    if (leftData.isValid()) // 检查leftData是否有效
    {
        // 将leftData转换为IModel的智能指针类型
        leftFilterData = qvariant_cast<QSharedPointer<IModel>>(leftData);
    }
    if(!leftFilterData) // 如果转换失败，直接返回false
        return false;

    QVariant rightData = source_right.data(Qt::UserRole); // 从source_right获取用户定义的角色数据
    QSharedPointer<IModel> rightFilterData = nullptr;
    if (rightData.isValid()) // 检查rightData是否有效
    {
        // 将rightData转换为IModel的智能指针类型
        rightFilterData = qvariant_cast<QSharedPointer<IModel>>(rightData);
    }
    if(!rightFilterData) // 如果转换失败，直接返回false
        return false;

    // 获取两个索引项对应的数据字段值，基于sortField()指定的字段进行比较
    auto leftValue = leftFilterData->getFieldValueByFielddName(this->sortField());
    auto rightValue = rightFilterData->getFieldValueByFielddName(this->sortField());
    //return leftValue < rightValue; // 返回比较结果
}

QString CFilterModel::sortField() const
{
    return m_sortField;
}

void CFilterModel::setSortField(const QString &sortField)
{
    m_sortField = sortField;
}

void CFilterModel::setFilterList(const QList<QPair<QString, QString> > &filterList)
{
    m_filterList = filterList;
}

void CFilterModel::clearFilter()
{
    clearFilterList();
    invalidateFilter();
}

QList<QPair<QString, QString> > CFilterModel::filterList() const
{
    return m_filterList;
}
